package com.dfec.book.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dfec.book.constant.BorrowStatusEnum;
import com.dfec.book.dao.BorrowRecordDao;
import com.dfec.book.entity.BookEntity;
import com.dfec.book.entity.BorrowRecordEntity;
import com.dfec.book.exception.ServiceException;
import com.dfec.book.service.BookService;
import com.dfec.book.service.BorrowRecordService;
import com.dfec.book.util.PageUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 借阅记录服务实现类
 *
 * @author tangrg
 * @email 1446232546@qq.com
 * @date 2025-06-19 09:47:56
 */
@Service
@Transactional
public class BorrowRecordServiceImpl extends ServiceImpl<BorrowRecordDao, BorrowRecordEntity> implements BorrowRecordService {

    private static final int TERM_DAY = 30;


    private final BookService bookService;

    @Autowired
    public BorrowRecordServiceImpl(BookService bookService) {
        this.bookService = bookService;
    }

    private static void checkParam(BorrowRecordEntity borrowRecord) {
        if (StringUtils.isNotBlank(borrowRecord.getBorrower())) {
            BorrowStatusEnum borrowStatusEnum = BorrowStatusEnum.of(borrowRecord.getReturnStatus());
            if (borrowStatusEnum == BorrowStatusEnum.UNKNOWN) {
                throw new ServiceException("借阅状态参数错误");
            }
        }
    }

    @Override
    public PageUtils getRecordsByPage(BorrowRecordEntity borrowRecord) {

        checkParam(borrowRecord);

        Page<BorrowRecordEntity> page = new Page<>(borrowRecord.getPageNo(), borrowRecord.getPageSize());
        IPage<BorrowRecordEntity> borrowRecordEntityIPage = baseMapper.selectPage(page, borrowRecord);
        //默认借阅时间为30天，根据图书的创建时间计算到期时间
        for (BorrowRecordEntity record : borrowRecordEntityIPage.getRecords()) {
            record.setOughtReturnDate(record.getBorrowDate().plusDays(TERM_DAY));
        }

        return new PageUtils(borrowRecordEntityIPage);
    }

    @Override
    public boolean borrowBook(BorrowRecordEntity record) {
        // 验证图书是否存在且可借
        BookEntity book = bookService.getById(record.getBookId());
        if (book == null) {
            throw new ServiceException("图书不存在");
        }
        if (book.getIsBorrowed()) {
            throw new ServiceException("图书已被借出");
        }

        // 设置借出时间
        record.setBorrowDate(LocalDateTime.now());

        // 保存借阅记录
        boolean result = save(record);

        // 更新图书状态为已借出
        if (result) {
            bookService.updateBookBorrowStatus(record.getBookId(), true);
        }

        return result;
    }

    @Override
    public boolean returnBook(Integer recordId) {
        // 获取借阅记录
        BorrowRecordEntity record = getById(recordId);
        if (record == null) {
            throw new ServiceException("借阅记录不存在");
        }

        // 检查是否已归还
        if (record.getReturnDate() != null) {
            throw new ServiceException("图书已归还，不能重复操作");
        }

        // 设置归还时间
        record.setReturnDate(LocalDateTime.now());

        // 更新记录
        boolean result = updateById(record);

        // 更新图书状态为可借
        if (result) {
            bookService.updateBookBorrowStatus(record.getBookId(), false);
        }

        return result;
    }

    @Override
    public List<BorrowRecordEntity> getRecordsByBorrower(String borrower) {
        QueryWrapper<BorrowRecordEntity> query = new QueryWrapper<>();
        query.eq("borrower", borrower).orderByDesc("borrow_date");
        return list(query);
    }

    @Override
    public List<BorrowRecordEntity> getRecordsByBook(Integer bookId) {
        QueryWrapper<BorrowRecordEntity> query = new QueryWrapper<>();
        query.eq("book_id", bookId).orderByDesc("borrow_date");
        return list(query);
    }

    @Override
    public List<BorrowRecordEntity> getUnreturnedRecords() {
        QueryWrapper<BorrowRecordEntity> query = new QueryWrapper<>();
        query.isNull("return_date");
        return list(query);
    }


    @Override
    public List<BorrowRecordEntity> getOverdueRecords() {
        List<BorrowRecordEntity> unreturned = getUnreturnedRecords();
        return unreturned;
    }
}